<!--
* @FileDescription: 曲线图表组件
* @Author: yuec621@outlook.com
* @Date: 2024-11-10 12:24:01
 * @LastEditors: Please set LastEditors
 * @LastEditTime: 2024-12-30 12:25:16
-->
<template>
    <div class="chartBox" style="position: relative">
        <div ref="chartRef" class="w100 h100 content" id="chartId" style="height: 500px"></div>
        <symbolCard v-if="state.symShow&&!micaiChart" :symbolObj="state.symbolObj" :style="{
        position: 'absolute',
        left: state.xydata.x + 'px',
        top: state.xydata.y + 'px',
        zIndex: 122,
      }" @mouseleave="mouseleavesymbol"></symbolCard>
        <SymbolCardM v-if="state.symShow&&micaiChart" :symbolObj="state.symbolObjM" :style="{
        position: 'absolute',
        left: state.xydata.x + 'px',
        top: state.xydata.y + 'px',
        zIndex: 122,
      }" @mouseleave="mouseleavesymbol"></SymbolCardM>
        <youBoxCom v-if="state.youBoxShow" :style="{
        position: 'absolute',
        left: state.youXY.x * 2 + 'px',
        bottom: toolType == '5' ? 60 + '%' : state.youXY.y * 3 + '%',
        zIndex: 1,
      }" :youBoxList="state.youBoxList">
        </youBoxCom>
    </div>
</template>
<script setup>
    import {
        computed,
        nextTick,
        reactive,
        watchEffect
    } from "vue";
    import symbolCard from "./symbolCard.vue";
    import SymbolCardM from "./symbolCardM.vue";
    import youBoxCom from "./youBoxCom.vue";
    import printJS from "print-js";
    import * as echarts from "echarts";
    import dayjs from "dayjs";
    import _ from "lodash";
    import useUserStore from "@/store/modules/user";
    import imgIcon from "@/assets/images/youbiao.png";
    const {
        proxy
    } = getCurrentInstance();
    const userStore = useUserStore();
    const emits = defineEmits(["toolChange"]);
    const props = defineProps({
        micaiChart: {
            type: Boolean,
            default: () => {
                return false
            },
        },
        chartList: {
            type: Object,
            default: () => {
                return {};
            },
        },
        attrObj: {
            type: Object,
            default: () => {
                return undefined;
            },
        },
        alarmList: {
            type: Object,
            default: () => {
                return {};
            },
        },
        symbolShow: {
            type: String,
            default: () => {
                return "none";
            },
        },
        splitNumber: {
            type: Number,
            default: () => {
                return 20;
            },
        },
        toolType: {
            type: String,
            default: () => {
                return "";
            },
        },
        timeRange: {
            type: Array,
            default: () => {
                return [];
            },
        },
        maxMinScale: {
            type: Object,
            default: () => {
                return {
                    upperRestriction: undefined,
                    lowerRestriction: undefined
                }
            }
        }
    });
    // 重点
    const state = reactive({
        chartShow: true,
        xydata: {
            x: 0,
            y: 0,
        },
        symShow: false,
        symbolObj: {},
        symbolShow: false,
        splitNumber: 10,
        youXY: {
            x: 0,
            y: 0,
        },
        youBoxShow: false,
        youBoxList: [],
        maxMinScale: {},
        symbolObjM: {},
        chartList: [],
        alarmList: []
    });
    // 拐点悬浮框
    function mouseleavesymbol() {
        state.symShow = false
    }
    let chartCon;

    function setC1(arr, alarmList) {
        let xdata = [];
        let serArr = [];
        let xdataalarm = [];
        let serArralarm = [];
        if (JSON.stringify(arr) != "{}") {
            if (arr.allTimes.length > 0) {
                xdata = arr.allTimes.map((item) => {
                    return props.micaiChart ? item : dayjs(item).format("YYYY-MM-DD HH:mm:ss");
                });
            } else {
                xdata = props.timeRange;
            }
            arr.hisSimulateLines.forEach((item, index) => {
                serArr.push({
                    name: item.pointId + item.place,
                    type: "line",
                    smooth: item.attrObj && item.attrObj
                        .maxchartType ? item.attrObj
                        .maxchartType : false,
                    symbolSize: 8,
                    xAxisIndex: 0,
                    symbol: props.symbolShow ||
                        (item.attrObj && item.attrObj.maxdotSwitch) ||
                        (props.attrObj && props.attrObj.chartDot) ?
                        "circle" : "none", //"circle",
                    itemStyle: {
                        color: item.color != null ? item.color : item.attrObj && item.attrObj
                            .maxlineColor ? item.attrObj.maxlineColor : 'rgba(68, 170, 255, 1)'
                    },
                    lineStyle: {
                        width: item.attrObj && item.attrObj.maxlineWidth ?
                            item.attrObj.maxlineWidth : 2,
                        opacity: item.maxShow ? item.opacitymax : item.opacity,
                        color: item.color != null ? item.color : item.attrObj && item.attrObj
                            .maxlineColor ? item.attrObj.maxlineColor : 'rgba(68, 170, 255, 1)',
                        type: item.attrObj && item.attrObj
                            .maxlineType ? item.attrObj
                            .maxlineType : false,
                    },
                    data: item.hisSimulatePoints && item.hisSimulatePoints.map((itemsub) => {
                        return itemsub.type == '密' ? [
                            itemsub.dataTime,
                            itemsub.pointValue,
                        ] : [
                            dayjs(itemsub.dataTime).format("YYYY-MM-DD HH:mm:ss"),
                            itemsub.maxValue,
                        ];
                    }),
                }, {
                    name: item.pointId + item.place,
                    type: "line",
                    smooth: item.attrObj && item.attrObj
                        .minchartType ? item.attrObj
                        .minchartType : false,
                    symbolSize: 8,
                    xAxisIndex: 0,
                    symbol: props.symbolShow ||
                        (item.attrObj && item.attrObj.mindotSwitch) ||
                        (props.attrObj && props.attrObj.chartDot) ?
                        "circle" : "none", //"circle",
                    itemStyle: {
                        color: item.color != null ? item.color : item.attrObj && item.attrObj
                            .minlineColor ? item.attrObj.minlineColor : 'rgba(102, 136, 255, 1)'
                    },
                    lineStyle: {
                        width: item.attrObj && item.attrObj.minlineWidth ?
                            item.attrObj.minlineWidth : 2,
                        opacity: item.maxShow ? item.opacitymin : item.opacity,
                        color: item.color != null ? item.color : item.attrObj && item.attrObj
                            .minlineColor ? item.attrObj.minlineColor : 'rgba(102, 136, 255, 1)',
                        type: item.attrObj && item.attrObj
                            .minlineType ? item.attrObj
                            .minlineType : false,
                    },
                    data: item.hisSimulatePoints && item.hisSimulatePoints.map((itemsub) => {
                        return [
                            dayjs(itemsub.dataTime).format("YYYY-MM-DD HH:mm:ss"),
                            itemsub.minValue,
                        ];
                    }),
                }, {
                    name: item.pointId + item.place,
                    type: "line",
                    smooth: item.attrObj && item.attrObj
                        .avgchartType ? item.attrObj
                        .avgchartType : false,
                    symbolSize: 8,
                    xAxisIndex: 0,
                    symbol: props.symbolShow ||
                        (item.attrObj && item.attrObj.avgdotSwitch) ||
                        (props.attrObj && props.attrObj.chartDot) ?
                        "circle" : "none", //"circle",
                    itemStyle: {
                        color: item.color != null ? item.color : item.attrObj && item.attrObj
                            .avglineColor ? item.attrObj.avglineColor : 'rgba(221, 119, 238, 1)'
                    },
                    lineStyle: {
                        width: item.attrObj && item.attrObj.avglineWidth ?
                            item.attrObj.avglineWidth : 2,
                        opacity: item.maxShow ? item.opacityavg : item.opacity,
                        color: item.color != null ? item.color : item.attrObj && item.attrObj
                            .avglineColor ? item.attrObj.avglineColor : 'rgba(221, 119, 238, 1)',
                        type: item.attrObj && item.attrObj
                            .avglineType ? item.attrObj
                            .avglineType : false,
                    },
                    data: item.hisSimulatePoints && item.hisSimulatePoints.map((itemsub) => {
                        return [
                            dayjs(itemsub.dataTime).format("YYYY-MM-DD HH:mm:ss"),
                            itemsub.avgValue,
                        ];
                    }),
                });
            });
            if (JSON.stringify(alarmList) != "{}") {
                xdataalarm = alarmList.allTimes.map((item) => {
                    return dayjs(item).format("YYYY-MM-DD HH:mm:ss");
                });
                alarmList.hisAlarmLines.forEach((item) => {
                    serArralarm.push({
                        type: "line",
                        step: "start",
                        xAxisIndex: 1,
                        smooth: false,
                        symbol: "none",
                        tooltip: {
                            trigger: 'axis',
                            // 系列2的tooltip配置
                            formatter: function (params) {
                                // 自定义第二个坐标轴系列的tooltip内容
                                return '系列2: ' + params.value;
                            }
                        },
                        data: item.hisAlarmPoints.map((itemsub, index) => {
                            return [
                                dayjs(itemsub.dataTime).format("YYYY-MM-DD HH:mm:ss"),
                                itemsub.value,
                            ];
                        }),
                        itemStyle: {
                            normal: {
                                lineStyle: {
                                    color: item.type == 0 ?
                                        "rgba(255, 153, 0, 1)" : item.type == 1 ?
                                        "rgba(103, 194, 58, 1)" : item.type == 2 ?
                                        "rgba(245, 108, 108, 1)" : 'rgba(64, 158, 255, 1)',
                                    type: "dashed",
                                },
                            },
                        },
                    });
                });
            }
            serArr = serArr.concat(serArralarm);
        }
        let option = {
            tooltip: {
                formatter: function (param) {
                    if (param.length > 0) {
                        let arrNew = [];
                        let noData = []
                        let arrName = _.uniq(
                            param.map((item) => {
                                return {
                                    name: item.seriesName,
                                    idx: item.dataIndex,
                                };
                            })
                        );
                        console.log(arrName, "arrNamearrName")
                        if (JSON.stringify(arr) != "{}") {
                            console.log(arr.hisSimulateLines, "arr.hisSimulateLines")
                            arr.hisSimulateLines.forEach((item) => {
                                if (item.hisSimulatePoints == null) {
                                    noData.push({
                                        place:item.pointId+ item.sensorName,
                                        unit: undefined,
                                        dataTime:undefined,
                                    })
                                }
                                arrName.forEach((itemsub) => {
                                    if (itemsub.name == item.pointId + item
                                        .place) {
                                        arrNew.push({
                                            place: item.pointId+item.sensorName,
                                            unit: item.unit,
                                            ...item.hisSimulatePoints[
                                                itemsub
                                                .idx],
                                        });
                                    }
                                });
                            });
                        }
                        console.log(arrNew, "arrNewarrNew")
                        let youBoxArr = _.unionBy(arrNew, "pointId");
                        state.youBoxList = [{
                            place: "类型",
                            maxValue: "最大值",
                            minValue: "最小值",
                            avgValue: "平均值",
                            dataTime:undefined,
                            unit: undefined,
                        }, ].concat(youBoxArr).concat(noData);
                        state.youBoxShow = true;
                        state.youXY.x = param[0].dataIndex;
                    }
                },
            },
            title: {
                text: props.attrObj && props.attrObj.chartTitle,
                left: "center",
                top: 10,
            },
            toolbox: {
                show: true,
                y: "-30",
            },
            brush: {
                xAxisIndex: "all",
                brushLink: "all",
                seriesIndex: "all",
                // 选框中的视觉元素样式
                inBrush: {
                    symbol: "circle", // 图元图形 可以是'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin'
                    symbolSize: 32, // 图元大小
                    color: "red", // 图元颜色
                    colorAlpha: 0.5, // 图元透明度
                    opacity: 0.8, // 图元以及其附属物的透明度
                },
                // 未选中的视觉元素样式
                outOfBrush: {
                    symbol: "circle", // 图元图形 可以是'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin'
                    symbolSize: 32, // 图元大小
                    color: "red", // 图元颜色
                    colorAlpha: 0.5, // 图元透明度
                    opacity: 0.8, // 图元以及其附属物的透明度
                },
            },
            grid: {
                top: 50,
                left: 60,
                bottom: 30,
                right: 60,
            },
            xAxis: [{
                    name: props.attrObj && props.attrObj.chartX,
                    type: "category",
                    boundaryGap: false,
                    data: xdata,
                    axisLine: {
                        show: true,
                        lineStyle: {
                            color: "rgba(91, 109, 128, 0.8)",
                        },
                    },
                    axisTick: {
                        show: false,
                    },
                    axisLabel: {
                        show: true,
                        color: "rgba(62, 70, 79, 1)",
                    },
                    splitLine: {
                        show: props.attrObj && props.attrObj.chartGrid,
                        lineStyle: {
                            color: "rgba(91, 109, 128, 0.16)",
                            type: "dashed",
                        },
                    },
                    axisPointer: {
                        show: props.toolType == "5" || props.toolType == "6" ? true : false,
                        lineStyle: {
                            color: "#004E52",
                            opacity: 0.5,
                            width: 2,
                            type: "solid",
                        },
                        snap: false, //true必须在点上，false任意位置
                        handle: {
                            show: true,
                            size: 20,
                            margin: 60,
                            color: "#DC143C",
                            throttle: 100,
                            margin: -450,
                            icon: `image://${imgIcon}`,
                        },
                        triggerTooltip: true,
                        triggerEmphasis: true,
                    },
                },
                {
                    type: "category",
                    boundaryGap: false,
                    data: xdataalarm,
                    axisLine: {
                        show: false,
                        lineStyle: {
                            color: "rgba(91, 109, 128, 0.8)",
                        },
                    },
                    axisTick: {
                        show: false,
                    },
                    axisLabel: {
                        show: false,
                        color: "rgba(62, 70, 79, 1)",
                    },
                    splitLine: {
                        show: false,
                        lineStyle: {
                            color: "rgba(91, 109, 128, 0.16)",
                            type: "dashed",
                        },
                    },
                },
            ],
            yAxis: [{
                name: props.attrObj && props.attrObj.chartY,
                type: "value",
                // min: state.maxMinScale.lowerRestriction,
                // max: state.maxMinScale.upperRestriction,
                splitNumber: state.splitNumber, //纵向放大
                axisLine: {
                    show: true,
                    lineStyle: {
                        color: "rgba(91, 109, 128, 0.8)",
                    },
                },
                axisLabel: {
                    formatter: "{value}",
                    color: "rgba(62, 70, 79, 1)",
                },
                axisPointer: {
                    show: props.toolType == "6" ? true : false,
                    value: 200,

                    lineStyle: {
                        color: "#004E52",
                        opacity: 0.5,
                        width: 2,
                        type: "dashed",
                    },
                    label: {
                        formatter: function (param) {
                            state.youXY.y = props.toolType == "5" ? 35 : param.value;
                            return;
                        },
                    },
                    snap: false,
                    value: 100,
                    handle: {
                        show: true,
                        size: 20,
                        margin: 60,
                        color: "#DC143C",
                        throttle: 100,
                    },
                    triggerTooltip: false,
                },
                splitLine: {
                    show: props.attrObj && props.attrObj.chartGrid,
                    lineStyle: {
                        color: "rgba(91, 109, 128, 0.16)",
                        type: "dashed",
                    },
                },
            }, ],
            //   visualMap: {
            //     show: false,
            //     pieces: [
            //       {
            //         gt: 0,
            //         lte: 100,
            //         color: "red",
            //       },
            //       {
            //         gt: 100,
            //         color: "blue",
            //       },
            //     ],
            //     seriesIndex: 0,
            //   },
            series: serArr,
        };
        chartCon.setOption(option, true);
        chartCon.on("mouseover", function (param) {
            //拐点弹框位置及弹框数据
            if (param.event.offsetX > 1400) {
                param.event.offsetX = param.event.offsetX - 400;
            }
            state.xydata.x = param.event.offsetX;
            state.xydata.y = param.event.offsetY;
            state.symShow = true;
            if (JSON.stringify(arr) != "{}") {
                arr.hisSimulateLines.forEach((item) => {
                    if (param.seriesName == item.pointId + item.place) {
                        let dataObj = item.hisSimulatePoints[param.dataIndex];
                        if (!props.micaiChart) {
                            state.symbolObj = {
                                pointId: item.pointId,
                                pointName: item.sensorName,
                                place: item.place,
                                timeRange: [dataObj.intervalStart, dataObj.intervalEnd],
                                list: [{
                                        label: "最大值",
                                        value: dataObj.maxValue,
                                        unit: item.unit,
                                        state: item.color == null ? "blue" : item.color,
                                    },
                                    {
                                        label: "最大值时刻",
                                        unit: dayjs(dataObj.maxValueTime).format(
                                            "YYYY-MM-DD HH:mm:ss"),
                                    },
                                    {
                                        label: "最小值",
                                        value: dataObj.minValue,
                                        unit: item.unit,
                                        state: "blue",
                                    },
                                    {
                                        label: "平均值",
                                        value: dataObj.avgValue,
                                        unit: item.unit,
                                        state: "blue",
                                    },
                                    {
                                        label: "报警",
                                        value: dataObj.alarmNum,
                                        unit: item.unit,
                                        state: "blue",
                                    },
                                    {
                                        label: "累计时长",
                                        unit: dataObj.alarmDuration,
                                        state: "",
                                    },
                                    {
                                        label: "断电",
                                        value: dataObj.cutNum,
                                        unit: item.unit,
                                        state: "blue",
                                    },
                                    {
                                        label: "累计时长",
                                        unit: dataObj.cutDuration,
                                        state: "",
                                    },
                                    {
                                        label: "馈电异常",
                                        value: dataObj.feedNum,
                                        unit: item.unit,
                                        state: "blue",
                                    },
                                    {
                                        label: "累计时长",
                                        unit: dataObj.feedDuration,
                                        state: "",
                                    },
                                ],
                            };
                        } else {
                            state.symbolObjM = {
                                dataTime: dataObj.dataTime,
                                pointName: item.sensorName,
                                allStatus: dataObj.allStatus,
                                unit: dataObj.unit,
                                pointId: item.pointId,
                                pointValue: dataObj.pointValue,
                                list: dataObj.hisSerriedFeeds
                            };

                        }
                    }
                });
            }
        });

        if (props.toolType == "7") {
            chartCon.dispatchAction({
                type: "takeGlobalCursor",
                key: "brush",
                brushOption: {
                    brushType: "lineX", // 指定选框类型
                },
            });
        } else {
            chartCon.dispatchAction({
                type: "none",
                key: "brush",
                removeOnClick: true,
                brushOption: {
                    brushType: "clear", // 指定选框类型
                },
            });
        }
        chartCon.on("brushEnd", function (params) {
            if (params.areas.length != 0) {
                let start = params.areas[0].coordRange[0];
                let end = params.areas[0].coordRange[1];
                if (xdata.length > 0) {
                    let startTime = xdata[start];
                    let endTime = xdata[end];
                    emits("toolChange", {
                        type: "dateType",
                        data: [startTime, endTime],
                        brushValue: "7",
                    });
                }
            }
        });
    }
    watchEffect(() => {
        state.alarmList = props.alarmList
        state.chartList = props.chartList
        state.maxMinScale = props.maxMinScale
        if (props.toolType == '4') {
            state.symShow = false
        }
        if (props.toolType == "13") {
            let statesrc = chartCon.getDataURL({
                type: "png", //jpeg | jpeg
                pixelRatio: 1,
                backgroundColor: "#fff", //背景色白色
            });
            printJS({
                printable: statesrc, //表格的数据
                type: "image",
                imageStyle: "width:100%;height:100%; margin-bottom:0px;",
            });
        }
        if (props.toolType == "-1") {
            state.youBoxShow = false;
        }
        if (props.toolType == "12") {
            var picInfo = chartCon.getDataURL({
                type: "png",
                pixelRatio: 1.5, //放大两倍下载，之后压缩到同等大小展示。解决生成图片在移动端模糊问题
                backgroundColor: "#000",
            }); //获取到的是一串base64信息
            const elink = document.createElement("a");
            elink.download = "历史曲线图";
            elink.style.display = "none";
            elink.href = picInfo;
            document.body.appendChild(elink);
            elink.click();
            URL.revokeObjectURL(elink.href); // 释放URL 对象
            document.body.removeChild(elink);
        }
        if (JSON.stringify(props.chartList) != "{}") {
            state.symbolShow = props.symbolShow;
            state.splitNumber = props.splitNumber;
            nextTick(() => {
                chartCon = echarts.init(document.getElementById("chartId"));
                setC1(props.chartList, props.alarmList);
            });
        } else {
            nextTick(() => {
                // chartCon = echarts.init(document.getElementById("chartId"));
                // setC1({}, {})
            });
        }
    });
    onMounted(() => {
        window.addEventListener('resize', () => {
            if (chartCon) {
                chartCon.resize()
            }
        })
    });
</script>
<style lang="scss" scoped>
    .chartBox {
        width: 100%;
        height: 500px;
    }
</style>